package com.googlecode.imule.apps;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.util.Scanner;

import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;

import com.apple.dnssd.DNSSDException;
import com.googlecode.imule.apps.util.ListenerX;
import com.googlecode.imule.data.Action;
import com.googlecode.imule.data.Parse;
import com.googlecode.imule.data.UDPCommunicationX;
import com.googlecode.imule.discovery.Contact;
import com.googlecode.imule.discovery.DiscoveryServiceX;
import com.googlecode.imule.redundant.Components;

/**
 * A component that combines the discovery, communication modules of
 * the imule platform.
 * 
 * @author Neil Cowzer
 */
public class X {

	protected DiscoveryServiceX discovery;

	protected UDPCommunicationX communication;

	protected Components XMLparser;

	protected Digester digester;

	// the thread to aid communication
	private ListenerX listener;
	
	private boolean status;

	protected String name;
	
	protected String manifest;	// the manifest for the program

	public X(String name) throws SocketException, DNSSDException {
		this.name = name;
		communication = new UDPCommunicationX();
		discovery = new DiscoveryServiceX(name, communication.getInSocket());

		// add listener to this
		listener = new ListenerX(this, communication);
		listener.start();
	}

	public void print(String message){
		System.out.println(message);
	}

	public void execute(String xml){
		Action action = null;
		System.out.println();
		try {
			action = Parse.action(xml);
			
			if (action.getName().equalsIgnoreCase("setOn")){
				//System.out.println("please work");
				if (action.getArguments().get(0).getValue().equalsIgnoreCase("true"))
					setOn(true);
				else
					setOn(false);
			}
			
		} catch (IOException e){
		} catch (SAXException e){}
		

	}
	
	public void setOn(boolean status){
		System.out.println("turning On? "+status);
		this.status = status;
	}

	public void setManifest(String filename){
		manifest = "";
		try {
			BufferedReader reader = new BufferedReader(new FileReader(filename));
			String line = "";
			while (line != null){
				line = reader.readLine();
				manifest += line;
			}
		} catch (IOException e){}
	}

	public String getManifest(){
		return manifest;
	}

	public void sendAction(String serviceName) throws IOException{
		String message = Parse.Action(serviceName, "sampleMethod", "","2");
		send(message, serviceName);
	}
	
	public void sendAction(String serviceName, String method, String value) throws IOException{
		String message = Parse.Action(serviceName, method, "",value);
		send(message, serviceName);
	}

	public void send(String message, String serviceName) throws IOException{
		Contact contact = discovery.getContacts().getContact(serviceName);
		if (contact != null)
			communication.send(message, contact.getIpAddress(), contact.getPort());
	}

	public void broadcast(String message) throws IOException{
		for (Contact contact : discovery.getContacts()) {
			communication.send(message, contact.getIpAddress(), contact.getPort());
		}
	}

	public static void main(String[] args) throws DNSSDException, IOException {
		Scanner scanner = new Scanner(System.in);

		System.out.println("Whats my name biatch?");
		X test = new X(scanner.nextLine());
		test.setManifest("resources/manifests/light.xml");
		System.out.println(test.getManifest());
		String input = "";

		while(!input.equalsIgnoreCase("close")){
			input = scanner.nextLine();
			if(input.charAt(0) == '@'){
				String[] split = input.split("\\s");
				String serviceName = split[0].substring(1, split[0].length());
				if (split[1].equalsIgnoreCase("@ON")){
					test.sendAction(serviceName, "setOn", "true");
				} else if (split[1].equalsIgnoreCase("@OFF")) {
					test.sendAction(serviceName, "setOn", "false");
				} else {
					String message = "";
					for (int i = 1; i < split.length; i++) {
						message += split[i] + " ";
					}
					test.send(message, serviceName);
				}
			} else {
				test.broadcast(input);
			}
		}
		System.out.println("closing");

		System.exit(0);
	}
}
